﻿using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Weblications.Sango.Constant;
using Pixysoft.Tools;
using Pixysoft.Framework.Verifications;

namespace Pixysoft.Weblications.Sango.Formular
{
    class OfficerFormular
    {
        public const int default_upgrade_datetime = -1;

        /** 突飞猛进队列冷却时间 */
        public static long default_upgrade_extra_timespan = DateTimeCoder.Instance.MinuteToMilliSecond(20);

        /// <summary>
        /// officerLevel = 当前等级，计算出来的是下一个等级需要的经验值
        /// </summary>
        /// <param name="officerlevel"></param>
        /// <returns></returns>
        public static long LevelupExperience(long officerlevel)
        {
            //武将升级，初始化=17.5分钟，增量 = 35分钟。每分钟军魂 = 5.

            return (long)Math.Round((17.5 + 35 * officerlevel) * 5);
        }

        /// <summary>
        /// 突飞猛进获取经验值
        /// </summary>
        /// <param name="buildinglevel"></param>
        /// <returns></returns>
        public static long getUpgradeExtraExperienceValue(long buildinglevel)
        {
            // 20分钟对应的军魂消耗

            return 20 * 5 * 3;
        }

        /// <summary>
        /// 20分钟对应的军魂消耗
        /// </summary>
        /// <param name="buildinglevel"></param>
        /// <returns></returns>
        public static long getUpgradeExtraCostSoulValue(long buildinglevel)
        {
            return 20 * 5;
        }

        /// <summary>
        /// 判断武将是否训练中
        /// </summary>
        /// <param name="officer"></param>
        /// <returns></returns>
        public static bool officerIsTraining(Pixysoft.Weblications.Sango.Entities.Usr_Officer officer)
        {
            return officer.Upgradeenddate > GlobalTimer.Instance.ToTimeSequence();
        }

        /// <summary>
        /// 在指定时间内，获取升级经验值
        /// </summary>
        /// <param name="buildingLevel"></param>
        /// <param name="startdate"></param>
        /// <param name="enddate"></param>
        /// <param name="speedtypecode"></param>
        /// <returns></returns>
        public static long getUpgradingExperienceByBuilding(long buildingLevel, double startdate, long enddate, long speedtypecode)
        {
            double timespan = enddate - startdate;

            if (timespan <= 0)
                return 0;

            double expvalue = 5 * timespan / 1000 / 60;

            return (long)Math.Round(expvalue);
        }

        /// <summary>
        /// 武将升级
        /// </summary>
        /// <param name="officer"></param>
        /// <param name="increaseExp"></param>
        /// <param name="userLevel"></param>
        /// <param name="buildingLevel"></param>
        public static bool upgrade(Entities.Usr_Officer officer, double increaseExp, long mainBuildingLevel, long officerBuildingLevel)
        {
            if (increaseExp < 0)
                throw Exceptions.VerificationFailedException(officer, increaseExp, mainBuildingLevel, officerBuildingLevel);

            long officerLevel = officer.Officerlevel;

            long startofficerLevel = officerLevel;

            double officerCurrentExp = officer.Expvalue;

            double officerUpgradeExp = LevelupExperience(officerLevel);

            do
            {
                // 如果当前值+增量比升级要求小，则表示不会跨级，跳出循环

                if (officerCurrentExp + increaseExp < officerUpgradeExp)
                    break;

                // 否则跨级在计算

                officerLevel++;

                increaseExp -= (officerUpgradeExp - officerCurrentExp);

                officerCurrentExp = 0;

                officerUpgradeExp = LevelupExperience(officerLevel);
            }
            while (true);

            officer.Expvalue = (long)Math.Ceiling(officerCurrentExp + increaseExp);

            officer.Upgradeexpvalue = (long)Math.Ceiling(officerUpgradeExp);

            officer.Officerlevel = officerLevel;

            officer.Hpbasevalue = GetOfficerHpValue(officerLevel);

            LoggerHelper.Debug("upgrade o:{0} incExp:{1} oBuilding.level:{2} mBuilding.level:{3} o.end.exp:{4} o.end.level:{5} o.end.levelupexp:{6}",//
                    officer.Primarycode, increaseExp, officerBuildingLevel, mainBuildingLevel,//
                    officer.Expvalue, officer.Officerlevel, officer.Upgradeexpvalue);

            if (officer.Officerlevel >= mainBuildingLevel)
            {
                long decreaseLevel = officer.Officerlevel - mainBuildingLevel;

                officer.Officerlevel = officer.Officerlevel - decreaseLevel;
                officer.Expvalue = 0;
                officer.Upgradeexpvalue = OfficerFormular.LevelupExperience(officer.Officerlevel);
                officer.Hpbasevalue = GetOfficerHpValue(officerLevel);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 取得武将生命值
        /// </summary>
        /// <returns></returns>
        public static long GetOfficerHpValue(long officerLevel)
        {
            return 200 + officerLevel * 50;
        }

        /// <summary>
        /// 开始训练，使用军魂
        /// </summary>
        /// <param name="buildingLevel"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        internal static long getUpgradeTimeModeCostSoulPrice(long buildingLevel, long mode)
        {
            return getUpgradeTimeModeTimeSpan(mode) / 1000 / 60 * 5;
        }

        /// <summary>
        /// 武将升级时间
        /// </summary>
        /// <param name="timeMode"></param>
        /// <returns></returns>
        public static long getUpgradeTimeModeTimeSpan(long timeMode)
        {
            switch (timeMode)
            {
                case UpgradeTimeTypecodeCollection.MODE_1:
                    return DateTimeCoder.Instance.HourToMilliSecond(1);
                case UpgradeTimeTypecodeCollection.MODE_2:
                    return DateTimeCoder.Instance.HourToMilliSecond(4);
                case UpgradeTimeTypecodeCollection.MODE_3:
                    return DateTimeCoder.Instance.HourToMilliSecond(12);
                case UpgradeTimeTypecodeCollection.MODE_4:
                    return DateTimeCoder.Instance.HourToMilliSecond(24);
                default:
                    return 0;
            }
        }

    }
}
